package database.local;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.swing.plaf.basic.BasicInternalFrameTitlePane.MaximizeAction;

import android.os.Parcel;
import android.os.Parcelable;

import server.SaveZoneHttpConnection;
import server.ServerObject;
import server.XmlParser;

public class Deal extends ServerObject implements Comparable<Deal>, Parcelable {
	
	private static final int SHORT_NAME_LIMIT = 20;
	
	/*consts for deal types*/
	public static final int BIRTHDAY = 1;
	public static final int BEER = 2;
	public static final int WINE = 3;
	public static final int CHASER = 4;
	public static final int COCKTAIL = 5;
	public static final int MEAT = 6;
	public static final int DESSERT = 7;
	public static final int ASIAN_FOOD = 8;
	public static final int ITALIAN_FOOD = 9;
	public static final int HOT_DRINK = 10;
	public static final int BREAKFAST = 11;
	
	/*default deal types equals to business types*/
	public static final int REST = 12;
	public static final int PUB = 13;
	public static final int PARTY = 14;
	
	
	private String business_item;
	private String name;
	private String dealInfo;
	private int deal_type;
	private String time;
	private String delta_time;
	private int days_bitmap; 
	private int rate_sum;
	private int rate_num;
	private int cost_level_sum;
	private int cost_level_num;
	private int to_rate;
	private int to_cost_level; 
	
	private List<Comment> comments;
	
	public Deal() {
		super();
		setDealInfo("");
		setDeal_type(12);
		setTime("");
		setDelta_time("");
		setRate_num(0);
		setRate_sum(0);
		setCost_level_num(0);
		setCost_level_sum(0);
		setTo_rate(-1);
		setTo_cost_level(-1);
		setDays_bitmap(QueryData.ALL_DAYS);
		setBusiness_item(null);
		setComments(new ArrayList<Comment>());
	}
	
	public String getDealInfo() {
		return dealInfo.trim();
	}
	public void setDealInfo(String dealInfo) {
		this.dealInfo = dealInfo;
	}
	/**
	 * @return the deal_type
	 */
	public int getDeal_type() {
		return deal_type;
	}

	/**
	 * @param deal_type the deal_type to set
	 */
	public void setDeal_type(int deal_type) {
		this.deal_type = deal_type;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getTime() {
		return time;
	}

	public void setTime(String time) {
		this.time = time;
	}

	public String getDelta_time() {
		return delta_time;
	}

	public void setDelta_time(String delta_time) {
		this.delta_time = delta_time;
	}

	
	/**
	 * @return the days_bitmap
	 */
	public int getDays_bitmap() {
		return days_bitmap;
	}

	/**
	 * @param days_bitmap the days_bitmap to set
	 */
	public void setDays_bitmap(int days_bitmap) {
		this.days_bitmap = days_bitmap;
	}

	public String toXml(){
		return XmlParser.dealToXml(this);
	}

	public int getRate_sum() {
		return rate_sum;
	}

	public void setRate_sum(int rate_sum) {
		this.rate_sum = rate_sum;
	}

	public int getRate_num() {
		return rate_num;
	}

	public void setRate_num(int rate_num) {
		this.rate_num = rate_num;
	}
	
	public int getRate() {
		if (rate_num == 0) return 1;
		return (rate_sum/rate_num) + 1;
	}
	
	public int getCostLevel() {
		if (cost_level_num == 0) return 1;
		return (cost_level_sum/cost_level_num) + 1;
	}
	
	/**
	 * @return the cost_level_sum
	 */
	public int getCost_level_sum() {
		return cost_level_sum;
	}

	/**
	 * @param cost_level_sum the cost_level_sum to set
	 */
	public void setCost_level_sum(int cost_level_sum) {
		this.cost_level_sum = cost_level_sum;
	}

	/**
	 * @return the cost_level_num
	 */
	public int getCost_level_num() {
		return cost_level_num;
	}

	/**
	 * @param cost_level_num the cost_level_num to set
	 */
	public void setCost_level_num(int cost_level_num) {
		this.cost_level_num = cost_level_num;
	}

	/*compared by rating*/
	public int compareTo(Deal other) {
		if (other == null) return -1;
		if (other.getRate() == this.getRate()) {
			if (this.getRate_num() > other.getRate_num()) return -1;
			else if (this.getRate_num() < other.getRate_num()) return 1;
				 else return 0;
		}
		if (this.getRate() > other.getRate()) return -1;
		else return 1;
	}

	public String getBusiness_item() {
		return business_item;
	}

	public void setBusiness_item(String business_item) {
		this.business_item = business_item;
	}

	/**
	 * 
	 * @param rate - int between 1 to 5 
	 */
	public void rateMe(int rate) {
		if (rate < 1 || rate > 5) return;
		SaveZoneHttpConnection.rateDeal(this, rate-1);
	}
	
	/**
	 * report as fake
	 */
	public void fakeMe(User user) {
		SaveZoneHttpConnection.reportFakeDeal(user, this);
	}
	
	/**
	 * @return the to_rate
	 */
	public int getTo_rate() {
		return to_rate;
	}

	/**
	 * @param to_rate the to_rate to set
	 * to_rate == 1..5 ==>the deal will be rated when use business.syncWithMainDataBase
	 */
	public void setTo_rate(int to_rate) {
		if (to_rate < 1 || to_rate > 5) return;
		this.to_rate = to_rate - 1;
	}

	/**
	 * 
	 * @param cost_level - int between 1 to 3 
	 */
	public void costLeveledMe(int cost_level) {
		if (cost_level < 1 || cost_level > 3) return;
		SaveZoneHttpConnection.costLevelDeal(this, cost_level -1);
	}
	
	/**
	 * @return the to_cost_level
	 */
	public int getTo_cost_level() {
		return to_cost_level - 1;
	}

	/**
	 * @param to_cost_level the to_cost_level to set
	 * to_cost_level 1..3. the deal will be cost level when use business.syncWithMainDataBase
	 */
	public void setTo_cost_level(int to_cost_level) {
		if (to_cost_level < 1 || to_cost_level > 3) return;
		this.to_cost_level = to_cost_level;
	}

	public void commentMe(String comment_str, int rate, int cost_level, User user) {
		if (cost_level < 1 || cost_level > 3) return;
		if (rate < 1 || rate > 5) return;
		if (comment_str == null)
			comment_str = "";
		SaveZoneHttpConnection.commentDeal(this, comment_str, rate, cost_level, user);
	}
	
	public void deleteMe(User user) {
		if (user == null) return;
		SaveZoneHttpConnection.deleteDeal(this, user);
	}

	/**
	 * @return the comments
	 */
	public List<Comment> getComments() {
		Collections.sort(comments);
		
		return comments;
	}

	/**
	 * @param comments the comments to set
	 */
	public void setComments(List<Comment> comments) {
		this.comments = comments;
	}
	
	public void likeMe(User user) {
		SaveZoneHttpConnection.likeDeal(user, deal_type);
	}
	/**
	 * 
	 * @return shrter version of the name limit = SHORT_NAME_LIMIT
	 */
	public String getShortName() {
		return getShortName(SHORT_NAME_LIMIT);
		
	}
	
	
	public String getShortName(int length) {
		String short_name = this.name;
		if (short_name == null || short_name.matches("")) 
			short_name = getDealInfo();
		
		if (short_name == null) return "";
		if (short_name.length() <= length) return short_name;
		
		int temp;
		int next_word_index = short_name.indexOf(' ', length);
		if (next_word_index != -1 && next_word_index <= 2*length) {
			short_name = short_name.substring(0, next_word_index);
			return short_name.concat("...");
		}
		
		next_word_index = short_name.indexOf('\n', length);
		if (next_word_index != -1 && next_word_index <= 2*length) {
			short_name.substring(0, next_word_index);
			return short_name.concat("...");
		}
		
		if (short_name.length() <= 2*length) return short_name;
		
		/*otherwise unexpected problem*/
		return short_name;
		
		
	}
	
	
	
	
	/* Parcelable implements methods */
	
	public Deal (Parcel in){
		super();
		readFromParcel(in);
	}

	public void readFromParcel(Parcel in) {
		super.readFromParcel(in);
		business_item = in.readString();
		name = in.readString();
		dealInfo = in.readString();
		deal_type = in.readInt();
		time = in.readString();
		delta_time = in.readString();
		days_bitmap = in.readInt();
		rate_sum = in.readInt();
		rate_num = in.readInt();
		cost_level_num = in.readInt();
		cost_level_sum = in.readInt();
		to_rate = in.readInt();
		to_cost_level = in.readInt();
		if (comments == null){
			comments = new ArrayList<Comment>();
		}
		
		in.readTypedList(comments, Comment.CREATOR);
		}

	public int describeContents() {
		return 0;
	}

	public void writeToParcel(Parcel dest, int flags) {
		super.writeToParcel(dest, flags);
		dest.writeString(business_item);
		dest.writeString(name);
		dest.writeString(dealInfo);
		dest.writeInt(deal_type);
		dest.writeString(time);
		dest.writeString(delta_time);
		dest.writeInt(days_bitmap); 
		dest.writeInt(rate_sum);
		dest.writeInt(rate_num);
		dest.writeInt(cost_level_num);
		dest.writeInt(cost_level_sum);
		dest.writeInt(to_rate);
		dest.writeInt(to_cost_level);
		dest.writeTypedList(comments);
	}
	
	public static final Parcelable.Creator CREATOR =
	    	new Parcelable.Creator() {
	            public Deal createFromParcel(Parcel in) {
	                return new Deal(in);
	            }
	 
	            public Deal[] newArray(int size) {
	                return new Deal[size];
	            }
	        };

}
